package com.danieltoms.gcSync.contact;

import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;

import net.rim.device.api.ui.component.Dialog;

public class BBContact
{
	private Contact _contact = null;

	public BBContact(Contact contact)
	{
		_contact = contact;
	}

	public Contact getContact()
	{
		return _contact;
	}

	private static int _maxEmails = 0;

	public static int getMaxEmails()
	{
		return _maxEmails;
	}

	static
	{

		try
		{
			ContactList list = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
			_maxEmails = list.maxValues(Contact.EMAIL);
		}
		catch (PIMException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	// title
	// picture -tbd
	// email
	// Company
	// Job Title
	// Work (phone)
	// Work 2 (phone 2)
	// Home (phone)
	// Home 2 (phone)
	// Mobile
	// Pager
	// Fax
	// Other (phone)
	// PIN
	// Work Address 1
	// Work Address 2
	// Work City
	// Work State/Prov
	// Work Zip/Postal Code
	// Home Address 1
	// Home Address 2
	// Home City
	// Home State/Prov
	// Home Zip/Postal Code
	// Web page
	// User 1,2,3,4 Can I get these if they change the name? yes, i can get the
	// lable value by PimList.getFieldLabel
	// Notes

	// Store any google specific fields in notes. First come user notes,
	/*
	 * then g IM: ICQ danny.toms@icw.com g IM: blah
	 * 
	 */

	// create the name as a single line in order to key against google contacts
	// follow whatever rules our options define
	public String getKey()
	{
		// if you have an email, that is the key, as google guarantees the
		// uniquenss of email to contact
		if (this.getEmail() == null || this.getEmail().equals(""))
			return this.getEmail();
		else
			// use the name as a key for contacts without an email. todo: handle
			// company only name
			return this.getFamilyName();

	}

	// aka first name

	public String getGivenName()
	{
		if (_contact.countValues(Contact.NAME) > 0)
		{
			String[] names = _contact.getStringArray(Contact.NAME, Contact.ATTR_NONE);
			return names[Contact.NAME_GIVEN];
		}

		return null;
	}

	public String getEmail()
	{
		if (_contact.countValues(Contact.EMAIL) > 0) { return _contact.getString(Contact.EMAIL, 0);

		}

		return null;
	}

	public Vector getEmails()
	{
		Vector vector = null;

		if (_contact.countValues(Contact.EMAIL) > 0)
		{
			vector = new Vector();
			vector.addElement(_contact.getString(Contact.EMAIL, 0));
		}
		if (_contact.countValues(Contact.EMAIL) > 1)
		{
			vector.addElement(_contact.getString(Contact.EMAIL, 1));
		}
		if (_contact.countValues(Contact.EMAIL) > 2)
		{
			vector.addElement(_contact.getString(Contact.EMAIL, 2));
		}
		return vector;
	}

	public int getEmailCount()
	{
		return _contact.countValues(Contact.EMAIL);

	}

	public void removeEmails()
	{
		while (_contact.countValues(Contact.EMAIL) > 0)
		{
			_contact.removeValue(Contact.EMAIL, 0);
		}
	}
	

	public void addEmail(String value)
	{
		if (value == null)
			value = "";

		_contact.addString(Contact.EMAIL, Contact.ATTR_NONE, value);
	}

	public String getFamilyName()
	{
		String[] names = _contact.getStringArray(Contact.NAME, Contact.ATTR_NONE);
		return names[Contact.NAME_FAMILY];
	}

	public void setFamilyName(String value)
	{
		if (value == null)
			value = "";

		String[] name = null;
		if (_contact.countValues(Contact.NAME) > 0)
		{
			name = _contact.getStringArray(Contact.NAME, Contact.ATTR_NONE);
			_contact.removeValue(Contact.NAME, 0);
		}
		else
			name = new String[_contact.getPIMList().stringArraySize(Contact.NAME)];

		name[Contact.NAME_FAMILY] = value;
		_contact.addStringArray(Contact.NAME, Contact.ATTR_NONE, name);
	}

	public void setGivenName(String value)
	{
		if (value == null)
			value = "";
		String[] name = null;
		if (_contact.countValues(Contact.NAME) > 0)
		{
			name = _contact.getStringArray(Contact.NAME, Contact.ATTR_NONE);
			_contact.removeValue(Contact.NAME, 0);
		}
		else
			name = new String[_contact.getPIMList().stringArraySize(Contact.NAME)];

		name[Contact.NAME_GIVEN] = value;
		_contact.addStringArray(Contact.NAME, Contact.ATTR_NONE, name);
	}

	public String getUID()
	{
		return _contact.getString(Contact.UID, 0);
	}

	public void setUID(String uid)
	{
		if (_contact.countValues(Contact.UID) == 1)
			_contact.removeValue(Contact.UID, 0);

		_contact.addString(Contact.UID, 0, uid);
	}

	public String getNotes()
	{
		if (_contact.countValues(Contact.NOTE) > 0)
			return _contact.getString(Contact.NOTE, 0);

		return null;
	}

	public void setNotes(String note)
	{
		if (note == null)
			note = "";

		if (_contact.countValues(Contact.NOTE) == 1)
			_contact.removeValue(Contact.NOTE, 0);

		_contact.addString(Contact.NOTE, 0, note);

	}

	public String getJobTitle()
	{
		if (_contact.countValues(Contact.TITLE) > 0)
			return _contact.getString(Contact.TITLE, 0);

		return null;
	}

	public void setJobTitle(String title)
	{
		if (title == null)
			title = "";
		if (_contact.countValues(Contact.TITLE) == 1)
			_contact.removeValue(Contact.TITLE, 0);

		_contact.addString(Contact.TITLE, 0, title);

	}

	public String getCompany()
	{
		if (_contact.countValues(Contact.ORG) > 0)
			return _contact.getString(Contact.ORG, 0);

		return null;
	}

	public void setCompany(String company)
	{

		if (company == null)
			company = "";

		if (_contact.countValues(Contact.ORG) == 1)
			_contact.removeValue(Contact.ORG, 0);

		_contact.addString(Contact.ORG, 0, company);
	}

	public String getHomeAddress1()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_STREET);
	}

	public void setHomeAddress1(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_STREET, value);

	}
	
	public String getHomeAddress2()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_EXTRA);
	}

	public void setHomeAddress2(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_EXTRA, value);
	
	}
	
	public String getHomeLocality()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_LOCALITY);
	}

	public void setHomeLocality(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_LOCALITY, value);
	
	}
	
	public String getHomeRegion()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_REGION);
	}

	public void setHomeRegion(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_REGION, value);
	
	}
	
	public String getHomePostalCode()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_POSTALCODE);
	}

	public void setHomePostalCode(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_POSTALCODE, value);
	
	}
		
	public String getHomeCountry()
	{
		return this.getAddressField(Contact.ATTR_HOME, Contact.ADDR_COUNTRY);
	}

	public void setHomeCountry(String value)
	{
		this.setAddressField(Contact.ATTR_HOME, Contact.ADDR_COUNTRY, value);
	
	}
	
	public String getWorkAddress1()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_STREET);
	}

	public void setWorkAddress1(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_STREET, value);

	}

	public String getWorkAddress2()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_EXTRA);
	}

	public void setWorkAddress2(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_EXTRA, value);
	
	}	
	
	public String getWorkLocality()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_LOCALITY);
	}

	public void setWorkLocality(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_LOCALITY, value);
	
	}
	
	public String getWorkRegion()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_REGION);
	}

	public void setWorkRegion(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_REGION, value);
	
	}
	
	public String getWorkPostalCode()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_POSTALCODE);
	}

	public void setWorkPostalCode(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_POSTALCODE, value);
	
	}
		
	public String getWorkCountry()
	{
		return this.getAddressField(Contact.ATTR_WORK, Contact.ADDR_COUNTRY);
	}

	public void setWorkCountry(String value)
	{
		this.setAddressField(Contact.ATTR_WORK, Contact.ADDR_COUNTRY, value);
	
	}	
	
	protected String getAddressField(int homeWorkType, int field)
	{
		String value = null;

		String[] address = null;

		int type = 0;
		int count = _contact.countValues(Contact.ADDR);
		// if no addresses at all return

		if (count == 0)
			return null;

		type = _contact.getAttributes(Contact.ADDR, 0);

		if (type == homeWorkType)
		{
			address = _contact.getStringArray(Contact.ADDR, 0);
			value = address[field];

		}
		else if (count == 2)
		{
			type = _contact.getAttributes(Contact.ADDR, 1);

			if (type == homeWorkType)
			{
				address = _contact.getStringArray(Contact.ADDR, 1);
				value = address[field];
			}
		}
		System.out.println("get Address Field returns: " + value);
		return value;
	}
	
	protected void setAddressField(int homeWorkType, int field, String value)
	{
		
		if (value == null)
			value = "";

		int type = 0;
		int insert = 0;
		int count = _contact.countValues(Contact.ADDR);


		String[] address = null;

		if (count != 0)
		{
			type = _contact.getAttributes(Contact.ADDR, 0);

			if (type == homeWorkType)
			{
				address = _contact.getStringArray(Contact.ADDR, 0);
				_contact.removeValue(Contact.ADDR, 0);
				insert = 0;
			}
			else if (count == 2)
			{
				type = _contact.getAttributes(Contact.ADDR, 1);

				if (type == homeWorkType)
				{
					address = _contact.getStringArray(Contact.ADDR, 1);
					_contact.removeValue(Contact.ADDR, 1);
					insert = 1;
				}
			}
			else
			{
				insert = 1;
				address = new String[_contact.getPIMList().stringArraySize(Contact.ADDR)];
			}
		}
		else
		{
			address = new String[_contact.getPIMList().stringArraySize(Contact.ADDR)];
			insert = Contact.ATTR_HOME;
		}

		address[field] = value;

		_contact.addStringArray(Contact.ADDR, insert, address);

	}
	
	public void commit() throws PIMException
	{
		_contact.commit();
	}

	public static Contact flattenAddress(Contact contact)
	{
		BBContact bbContact = new BBContact(contact);
		String address = bbContact.getWorkAddress2();

		/*
		 * 
if every bb field is filled out, then we sync fields based on commas.

if you edit the bb UI, and you save, and you don't have all addy fields filled out, it gets flattened into address 1 maybe we popup to warn
so you would have to redit if you messed up -

 To sync with google, you may only populate the Address 1 field, or you must populate all fields.  Your edit has been moved into Address 1.

so when we sync with goolge, either


		 */
		
		if (bbContact.getHomeAddress2() != null && !bbContact.getHomeAddress2().equals(""))
		{

			Dialog.alert("To sync with google, you may only populate the Address 1 field, or you must populate all fields.  Your edit has been moved into Address 1.");

			// we can't commit the above Contact, so search for a new instance
			// of it
			// should only find one, as the UID is part of the criteria
			try
			{
				ContactList list = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);

				Enumeration e = list.items(bbContact.getContact());

				BBContact update = new BBContact((Contact) e.nextElement());

				update.setHomeAddress2(null);
				update.commit();
				contact = update.getContact();

			}
			catch (PIMException e1)
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
				System.out.println("PIMException: " + e1.getMessage());
			}

		}

		if (address != null && !address.equals(""))
		{

			// Dialog.alert("gcSync settings do not allow use of address fields
			// other than Address 1");

			// we can't commit the above Contact, so search for a new instance
			// of it
			// should only find one, as the UID is part of the criteria
			try
			{
				ContactList list = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);

				Enumeration e = list.items(bbContact.getContact());

				BBContact update = new BBContact((Contact) e.nextElement());

				update.setWorkAddress2(null);
				update.commit();
				contact = update.getContact();
			}
			catch (PIMException e1)
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
				System.out.println("PIMException: " + e1.getMessage());
			}

		}

		return contact;
	}

	/*
	 * 
	 * String[] name = new String[list.stringArraySize(Contact.NAME)];
	 * name[Contact.NAME_GIVEN] = c.getNameGiven(); // name[Contact.NAME_FAMILY] =
	 * "Super Last Name";
	 * 
	 * contact.addStringArray(Contact.NAME, Contact.ATTR_NONE, name);
	 * 
	 * contact.addString(Contact.TEL, Contact.ATTR_HOME, c.getHomePhone());
	 * contact.addString(Contact.TEL, Contact.ATTR_MOBILE, c .getMobilePhone());
	 */

	public void delete() throws PIMException
	{
		// TODO Auto-generated method stub
		((ContactList) _contact.getPIMList()).removeContact(_contact);
	}

}
